/*
 * Copyright (c) 2016 moondev.cn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cn.moondev.moonlog.delegate;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import cn.moondev.moonlog.delegate.mq.Producer;
import cn.moondev.moonlog.delegate.mq.ProducerFactory;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;

import ch.qos.logback.core.Layout;
import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
import ch.qos.logback.core.rolling.RollingFileAppender;

/**
 * 为RollingFileAppender增加采集日志的实现
 * @param <E>
 * @date 2016年1月4日
 * @author chensc
 */
public class MonitorRollingFileAppender<E> extends RollingFileAppender<E> {

    /**
     * 是否需要监控,不需要监控时直接打印到文件，需要监控时在打印的同时会做相关的处理
     */
    public boolean monitor = true;

    /**
     * 采集类型，务必使用处理此种消息的spring bean名称,在处理消息的项目中将使用此属性实例化出具体的处理类<BR>
     * 在rocketmq中的每条消息的tag均为gatherType，所以在处理mq消息时可以直接使用gatherType直接从spring beanfactory中获取对应的处理类
     */
    public String gatherType;

    /**
     * 系统名字
     */
    public String sysName;

    /**
     * 监控时间的阀值,某个方法执行时间超过这个值才记录,如果为0或者空表示监控所有数据
     */
    public String threshold;

    @Override
    public void start() {
        Preconditions.checkNotNull(sysName,"sysName is null");
        Preconditions.checkNotNull(gatherType,"gatherType is null");
        super.start();
    }

    @Override
    protected void writeOut(E event) throws IOException {
        Layout<E> layout = null;
        if (null == encoder) {
            return;
        }

        if (encoder instanceof LayoutWrappingEncoder) {
            LayoutWrappingEncoder<E> lwe = (LayoutWrappingEncoder<E>) encoder;
            layout = lwe.getLayout();
        }

        if (null == layout) {
            return;
        }
        String msg = layout.doLayout(event);
        // 写日志
        super.writeOut(event);
        if (monitor) {
            Producer sender = ProducerFactory.getProducer();
            Map<String, Object> msgMap = new HashMap<String, Object>();
            String localIp = "127.0.0.1";
            msgMap.put("localIp", localIp);
            msgMap.put("sysName", sysName);
            msgMap.put("log", msg);
            msgMap.put("gatherType", gatherType);
            msgMap.put("timestamp", System.currentTimeMillis());
            msgMap.put("threshold", threshold);
            sender.send(gatherType,JSON.toJSONString(msgMap));
        }
    }

    public String getGatherType() {
        return gatherType;
    }

    public void setGatherType(String gatherType) {
        this.gatherType = gatherType;
    }

    public boolean isMonitor() {
        return monitor;
    }

    public void setMonitor(boolean monitor) {
        this.monitor = monitor;
    }

    public String getSysName() {
        return sysName;
    }

    public void setSysName(String sysName) {
        this.sysName = sysName;
    }

    public String getThreshold() {
        return threshold;
    }

    public void setThreshold(String threshold) {
        this.threshold = threshold;
    }
}
